package com.scs.application.modules.print.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.scs.application.core.consts.Const;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.service.IBaseFileService;
import com.scs.application.core.utils.BeanUtils;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.Tools;
import com.scs.application.modules.print.dto.TemplateDTO;
import com.scs.application.modules.print.entity.Template;
import com.scs.application.modules.print.mapper.TemplateMapper;
import com.scs.application.modules.print.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description:打印模板文件操作
 */
@Slf4j
@Service
public class FileTemplateServiceImpl extends BaseServiceImpl<TemplateMapper, Template> implements TemplateService, IBaseFileService {
    @Override
    public boolean removeCascadeById(Serializable id) {
        List<Template> templates = list();
        for (Template template : templates) {
            if (id.equals(template.getId())) {
                FileUtils.deleteFile(Const.PRINT_TEMP_SRC + template.getBusType() + ".json");
                break;
            }
        }
        return true;
    }

    @Override
    public Template getById(Serializable id) {
        Template template = null;
        List<Template> templates = list();
        for (Template template1 : templates) {
            if (id.equals(template1.getId())) {
                template = template1;
                break;
            }
        }
        return template;
    }

    @Override
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {
        List<Template> templates = list();
        for (Template template : templates) {
            if (idList.contains(template.getId())) {
                FileUtils.deleteFile(Const.PRINT_TEMP_SRC + template.getBusType() + ".json");
            }
        }
        return true;
    }

    @Override
    public Page<Template> page(QueryContext context) {
        List<Template> templates = list(context);
        return filePage(context, templates);
    }

    @Override
    public List<Template> list() {
        QueryContext context = new QueryContext();
        return list(context);
    }

    @Override
    public List<Template> list(QueryContext context) {
        List<TemplateDTO> templateDTOS = getDTOList();
        List<Template> templates = Lists.newArrayListWithCapacity(templateDTOS.size());
        for (TemplateDTO templateDTO : templateDTOS) {
            Template template = new Template();
            BeanUtils.copyProperties(templateDTO, template);
            templates.add(template);
        }
        if (context != null && context.getParams() != null) {
            String busType = context.getParams().get("busType") != null ? context.getParams().get("busType").toString() : "";
            templates = templates.stream().filter(template -> (StringUtils.isNotBlank(busType) ? template.getBusType().indexOf(busType) > -1 : true)).collect(Collectors.toList());
        }
        return templates;
    }

    @Override
    public TemplateDTO getTemplateDTO(String busType) {
        TemplateDTO templateDTO = new TemplateDTO();
        setTemplateDTO(templateDTO, Const.getPrintTempSrc() + busType + ".json");
        return templateDTO;
    }

    @Override
    public List<TemplateDTO> getDTOList() {
        return getDTOList(Const.getPrintTempSrc());
    }

    @Override
    public <Template> boolean saveBatch(Class<Template> modelClass, Collection<Template> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(Template template) {
        List<Template> templates = list();
        templates.stream().filter(temp -> temp.getBusType().equalsIgnoreCase(template.getBusType())
                && !temp.getId().equalsIgnoreCase(template.getId())).findAny().ifPresent(temp -> {
            throw new BusinessException("打印业务类型已经存在，不能重复添加！");
        });
        if (template.getId() == null) {
            template.setId(StringUtils.getIdStr());
        }
        File path = new File(Const.PRINT_TEMP_SRC);
        if (!path.exists()) {
            path.mkdirs();
        }

        String fileNameWithPath = Const.PRINT_TEMP_SRC + template.getBusType() + ".json";

        if (template.getGmtCreate() == null) {
            template.setGmtCreate(LocalDateTime.now());
            template.setCreator(Tools.getHostName());
        } else {
            template.setGmtModified(LocalDateTime.now());
            template.setModifier(Tools.getHostName());
        }
        TemplateDTO templateDTO = getTemplateDTO(template.getBusType());
        if (templateDTO == null) {
            templateDTO = new TemplateDTO();
        }
        BeanUtils.copyProperties(template, templateDTO);
        String result = JSON.toJSONString(templateDTO, SerializerFeature.PrettyFormat);
        FileUtils.writeTxtFile(fileNameWithPath, result);
        return true;
    }

    @Override
    public TemplateDTO getDTO(String fileSrc) {
        TemplateDTO templateDTO = new TemplateDTO();
        setTemplateDTO(templateDTO, fileSrc);
        if (StringUtils.isBlank(templateDTO.getBusType()) || StringUtils.isBlank(templateDTO.getId())) {
            return null;
        }
        return templateDTO;
    }

    private void setTemplateDTO(TemplateDTO templateDTO, String fileNameWithPath) {
        String templateString = FileUtils.readFileStore(fileNameWithPath);
        if (StringUtils.isEmpty(templateString)) {
            return;
        }
        JSONObject jsonObject = JSONObject.parseObject(templateString);
        templateDTO.setId(jsonObject.getString("id"))
                .setBusType(jsonObject.getString("busType"))
                .setPrintType(jsonObject.getString("printType"))
                .setConfigJson(jsonObject.getString("configJson"));
        String strTemplateFieldDTOS = jsonObject.getString("fieldDTOS");
        if (StringUtils.isNotBlank(strTemplateFieldDTOS)) {
            JSONArray jsonArray = JSONArray.parseArray(strTemplateFieldDTOS);
            if (jsonArray != null && !jsonArray.isEmpty()) {
                List<TemplateDTO.FieldDTO> fieldDTOS = Lists.newArrayListWithCapacity(jsonArray.size());
                jsonArray.forEach(obj -> {
                    JSONObject jsonObj = JSONObject.parseObject(obj.toString());
                    TemplateDTO.FieldDTO fieldDTO = new TemplateDTO.FieldDTO();
                    fieldDTO.setId(jsonObj.getString("id"))
                            .setTemplateId(jsonObj.getString("templateId"))
                            .setType(jsonObj.getString("type"))
                            .setField(jsonObj.getString("field"))
                            .setLabel(jsonObj.getString("label"))
                            .setSort(jsonObj.getInteger("sort"))
                            .setWidth(jsonObj.getInteger("width"))
                            .setSummary(jsonObj.getBoolean("summary"))
                            .setFontSize(jsonObj.getInteger("fontSize"))
                            .setFormat(jsonObj.getString("format"))
                            .setFlagGroup(jsonObj.getBoolean("flagGroup"))
                            .setDict(jsonObj.getString("dict"))
                            .setExpression(jsonObj.getString("expression"))
                            .setHideExpression(jsonObj.getString("hideExpression"))
                            .setFormation(jsonObj.getString("formation"))
                            .setFlagFontBold(jsonObj.getBoolean("flagFontBold"))
                            .setFlagLineFeed(jsonObj.getBoolean("flagLineFeed"))
                            .setOrderRule(jsonObj.getString("orderRule"))
                            .setFlagBreak(jsonObj.getBoolean("flagBreak"))
                            .setFlagShowNegative((jsonObj.getBoolean("flagShowNegative")))
                            .setFlagShareRow(jsonObj.getBoolean("flagShareRow"))
                            .setShareRow(jsonObj.getString("shareRow"))
                            .setAlignType(jsonObj.getString("alignType"));
                    fieldDTOS.add(fieldDTO);
                });
                templateDTO.setFieldDTOS(fieldDTOS);
            }
        }
    }

    @Override
    public TemplateDTO getDTOById(String templateId) {
        List<TemplateDTO> templateDTOS = getDTOList();
        Optional<TemplateDTO> optTemplateDTO = templateDTOS.stream().filter(templateDTO -> templateId.equalsIgnoreCase(templateDTO.getId())).findFirst();
        if (optTemplateDTO.isPresent()) {
            return optTemplateDTO.get();
        }
        return null;
    }

    @Override
    public Boolean isSupport(Boolean flagProject) {
        return !flagProject;
    }
}

